/*---------------------------------------
* Author:ZJ
* createDate:Friday, August 10, 2012
* Description:
*
------------------------------------------*/

#include "StdAfx.h"
#include "connection_manager.hpp"

namespace fly {

	namespace jld{

		namespace server {

			//insert connection_ptr into connections and start read or write for connection.
			void connection_manager::start(connection_ptr c)
			{
				connections_.insert(c);
				if (c->socket().is_open())
				{
					LOG_PRINTF("<%s>:<%d> ON.",c->socket().remote_endpoint().address().to_string().c_str(), c->socket().remote_endpoint().port());
				}
				LOG_PRINTF("Connection size: %d",connections_.size());
				c->start();
			}
			//stop connection
			void connection_manager::stop(connection_ptr c)
			{
				connections_.erase(c);
				if (c->socket().is_open())
				{
					LOG_PRINTF("<%s>:<%d> OFF.",c->socket().remote_endpoint().address().to_string().c_str(), c->socket().remote_endpoint().port());
				}
				LOG_PRINTF("Connection size: %d",connections_.size());
				c->stop();
			}
			//attackers.
			void connection_manager::attack(connection_ptr conn_ptr)
			{
				stop(conn_ptr);
				LOG_EMER("Add into attacker list");
			}
			//stop all connection and clear connections
			void connection_manager::stop_all()
			{
				for_each(connections_.begin(),connections_.end()
					,boost::bind(&connection::stop,_1));
				connections_.clear();
				LOG_NOTICE("Clear connections.");
			}

			//return current connections size.
			const size_t connection_manager::connection_size()
			{
				return connections_.size();
			}

			void connection_manager::send(connection_ptr cnn, queue<send_packet>& packets)
			{
				while (!packets.empty())
				{
					switch(packets.front().target)
					{
					case T_SELF:
						send_self(cnn, packets.front().buf);
						break;
					case T_SYN_TO:
						send_all(packets.front().buf);
						break;
					case T_SYN_FROM:
						send_all(packets.front().buf);
						break;
					case T_SYN_BOTH:
						send_all(packets.front().buf);
						break;
					case T_ALL:
						send_all(packets.front().buf);
						break;
					default:
						LOG_ERR("Unknown sending target");
						break;
					}
					packets.pop();
				}
			}

			//send msg to owner
			void connection_manager::send_self(connection_ptr cnn, const_buf_ptr const_send_buf)
			{
				cnn->asyn_write(const_send_buf);
			}

			void connection_manager::send_all(const_buf_ptr send_buf)
			{
				if(connections_.size() == 0)
				{
					LOG_WARN("Connections's size is zero.");
					return;
				}
				
				for_each(connections_.begin(),connections_.end()
					,boost::bind(&connection::asyn_write,_1,send_buf));
			}

		} // namespace server
	}
} // namespace servspace
